﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DynaPrecision.LinearSystem
{
	public class DoolittleDecomposedArraySolver
	{
		public static void UpdateResult<TData>(IMultiDimensionalArray<TData> input, IMultiDimensionalArray<TData> load, IMultiDimensionalArray<TData> result)
		{
			for (int i = 0; i < input.GetLength(0); i++)
			{
				result[i, 0] = load[i, 0];
				for (int k = 0; k < i; k++)
				{
					result[i, 0] = result[i, 0] - result[k, 0] * (dynamic)input[i, k];
				}
			}
			for (int i = input.GetLength(0) - 1; i >= 0; i--)
			{
				for (int k = input.GetLength(0) - 1; k > i; k--)
				{
					result[i, 0] = result[i, 0] - result[k, 0] * (dynamic)input[i, k];
				}
				result[i, 0] = result[i, 0] / (dynamic)input[i, i];
			}
			return;
		}
		public static void UpdateResult<TData>(IMultiDimensionalArray<TData> input, IMultiDimensionalArray<TData> load, IMultiDimensionalArray<TData> result, int halfBandWidth)
		{
			for (int i = 0; i < input.GetLength(0); i++)
			{
				result[i, 0] = load[i, 0];
				int k = 0 > i - halfBandWidth ? 0 : i - halfBandWidth;
				for (; k < i; k++)
				{
					result[i, 0] = result[i, 0] - result[k, 0] * (dynamic)input[i, k];
				}
			}
			for (int i = input.GetLength(0) - 1; i >= 0; i--)
			{
				int k = input.GetLength(0) - 1 > i + halfBandWidth ? i + halfBandWidth : input.GetLength(0) - 1;
				for (; k > i; k--)
				{
					result[i, 0] = result[i, 0] - result[k, 0] * (dynamic)input[i, k];
				}
				result[i, 0] = result[i, 0] / (dynamic)input[i, i];
			}
		}
		public static void UpdateResult<TData>(IMultiDimensionalArray<TData> input, IMultiDimensionalArray<TData> load, IMultiDimensionalArray<TData> result, int halfBandWidth, int lowerFullArrayCount)
		{
			for (int i = 0; i < input.GetLength(0); i++)
			{
				result[i, 0] = load[i, 0];
				int k = 0 > i - halfBandWidth ? 0 : i - halfBandWidth;
				if (!(i < input.GetLength(0) - lowerFullArrayCount)) k = 0;
				for (; k < i; k++)
				{
					result[i, 0] = result[i, 0] - result[k, 0] * (dynamic)input[i, k];
				}
			}
			for (int i = input.GetLength(0) - 1; i >= 0; i--)
			{
				int k;
				if (i + halfBandWidth >= input.GetLength(0) - lowerFullArrayCount)
				{
					k = input.GetLength(0) - 1;

					for (; k > i; k--)
					{
						result[i, 0] = result[i, 0] - result[k, 0] * (dynamic)input[i, k];
					}
				}
				else
				{
					k = input.GetLength(0) - 1;
					for (; k > input.GetLength(0) - halfBandWidth - 1; k--)
					{
						result[i, 0] = result[i, 0] - result[k, 0] * (dynamic)input[i, k];
					}
					k = i + halfBandWidth;

					for (; k > i; k--)
					{
						result[i, 0] = result[i, 0] - result[k, 0] * (dynamic)input[i, k];
					}
				}
				
				result[i, 0] = result[i, 0] / (dynamic)input[i, i];
			}
		}
	}
}
